/*
 * wifi.c
 *
 *  Created on: 2021年12月24日
 *      Author: soliber
 */

//Include
#include "wifi.h"
#include "gpio.h"

//Typedef


//Define
#define LOG_TAG "wifi"


//Macro
#define TURN_ON()	HAL_GPIO_WritePin(WIFI_EN_GPIO_Port, WIFI_EN_Pin, GPIO_PIN_SET)
#define TURN_OFF()	HAL_GPIO_WritePin(WIFI_EN_GPIO_Port, WIFI_EN_Pin, GPIO_PIN_RESET)
#define RST_ACTIVE()		HAL_GPIO_WritePin(WIFI_RST_GPIO_Port, WIFI_RST_Pin, GPIO_PIN_RESET)
#define RST_DISACTIVE()	HAL_GPIO_WritePin(WIFI_RST_GPIO_Port, WIFI_RST_Pin, GPIO_PIN_SET)

//Variables
static WIFI_Op_Status_t OpStatus = WIFI_OP_STATUS_INIT;

static osMutexId_t WIFI_MutexHandle;
const osMutexAttr_t WIFI_Mutex_attributes = {
  .name = "WIFI_Mutex"
};

static uint16_t Version = 0;
static uint32_t IP_Addr = 0;
static uint64_t MAC_Addr = 0;


//Function Prototypes
static void HardReset(void);

/**
 * @brief 硬件复位
 */
static void HardReset(void)
{
	///初始化UART
	///GPIO已在 @ref MX_GPIO_Init() 中初始化完成
	MX_USART2_UART_Init();

	///硬件复位
	TURN_ON();
	RST_ACTIVE();
	osDelay(1);
	RST_DISACTIVE();
}

/**
 * @brief WiFi加锁
 */
void WIFI_Lock(void)
{
	osStatus_t st;
	if(WIFI_MutexHandle==NULL)
	{
		WIFI_MutexHandle = osMutexNew(&WIFI_Mutex_attributes);
		assert(WIFI_MutexHandle!=NULL);
	}

	st = osMutexAcquire(WIFI_MutexHandle, 5000);
	if(st != osOK)
	{
		log_e("wifi lock error:%d",st);
		Error_Handler();
	}
}

/**
 * @brief WiFi解锁
 */
void WIFI_Unlock(void)
{
	osStatus_t st;
	st = osMutexRelease(WIFI_MutexHandle);
	if(st!=osOK)
	{
		log_e("wifi unlock error:%d",st);
		Error_Handler();
	}
}

/**
 * @brief 初始化WIFI模块
 */
void WIFI_Init(void)
{
	//加锁
	WIFI_Lock();

	if(OpStatus == WIFI_OP_STATUS_INIT)
	{
		//硬复位
		HardReset();
		log_i("hard reset");

		//初始化解析器
		ParserInit();
		log_i("start parser");

		//等待启动事件
		WaitStart(5000);
		log_i("module start");

		//进入AT模式
		assert(AT_Enter() == 0);
		log_i("enter AT mode");

		//查询版本
		AT_Execute("AT+GMR\r\n");
		assert(AT_Parser_GMR(&Version) == 0);
		log_i("wifi version:%04x",Version);

		//设置模块工作模式：TCP模式
		AT_Execute("AT+MODE=0\r\n");
		assert(AT_Parser_OK()==0);
		log_i("tcp mode");

		//设置TCP模式：自动+协议模式
		AT_Execute("AT+CIPMODE=1,1\r\n");
		assert(AT_Parser_OK()==0);
		log_i("tcp auto connect, protocol transfer");

		//设置TCP多连接
		AT_Execute("AT+CIPMUX="NUM_SOCKETS_STR"\r\n");
		assert(AT_Parser_OK()==0);
		log_i("tcp "NUM_SOCKETS_STR" links max");

		//设置AP连接模式:BLE配网
		AT_Execute("AT+CWAUTO=2\r\n");
		assert(AT_Parser_OK()==0);
		log_i("BLE config open");

		//获取蓝牙广播名称
		char name[30];
		AT_Execute("AT+BLENAME?\r\n");
		assert(AT_Parser_BLENAME(name)==0);
		log_i("BLE Name:%s",name);

		//退出AT模式
		assert(AT_Exit()==0);
		log_i("exit AT mode");

		//等待连接AP
		log_i("waiting 1 minutes for AP connect...");
		log_i("you can use BLE select AP");
		if(WaitAPConnect(60000)==1)
		{
			log_i("AP connect timeout! device will reset...");
			osDelay(2000);
			NVIC_SystemReset();
		}
		log_i("AP connected");

		//进入AT模式
		assert(AT_Enter() == 0);
		log_i("enter AT mode");

		//查询MAC地址
		AT_Execute("AT+CWMAC?\r\n");
		assert(AT_Parser_CWMAC(&MAC_Addr) == 0);
		log_i("mac:%02x:%02x:%02x:%02x:%02x",
				(MAC_Addr>>(8*5))&0xff,
				(MAC_Addr>>(8*4))&0xff,
				(MAC_Addr>>(8*3))&0xff,
				(MAC_Addr>>(8*2))&0xff,
				(MAC_Addr>>(8*1))&0xff,
				(MAC_Addr>>(8*0))&0xff
				);

		//查询IP地址
		AT_Execute("AT+CIFSR\r\n");
		assert(AT_Parser_CIFSR(&IP_Addr) == 0);
		log_i("ipv4:%d.%d.%d.%d",
				(IP_Addr>>(8*3))&0xff,
				(IP_Addr>>(8*2))&0xff,
				(IP_Addr>>(8*1))&0xff,
				(IP_Addr>>(8*0))&0xff);

		//退出AT模式
		assert(AT_Exit()==0);
		log_i("exit AT mode");
	}
	else
	{
		//已经初始化过
		log_i("wifi has been initialized");
	}

	//解锁
	WIFI_Unlock();
}

/**
 * @brief 解初始化WIFI模块
 */
void WIFI_DeInit(void)
{
	uint32_t ret;

	//断电
	TURN_OFF();

	//解初始化解析器
	ParserDeInit();

	//释放资源
	ret = osMutexDelete(WIFI_MutexHandle);
	assert(ret = osOK);

	//关闭串口
	ret = HAL_UART_DeInit(&wifi_uart);
	assert(ret == HAL_OK);
}
